<template>
  <el-dialog title="点位地图" :visible.sync="show" append-to-body width="90%" @closed="closed">
    <div ref="container" class="container" v-loading="taskRoutesLoading" element-loading-background="rgba(255, 255, 255, 0.5)" />
  </el-dialog>
</template>
<script>
// 任务路线地图
import { wgs84togcj02 } from '@/utils/coordTransform'
import { getTaskRoutes } from '@/api/cq/patrol'
const initLngLat = [118.1, 24.46667] // 厦门
const positionIcons = [
  require('@/assets/image/position_uncheck.png'),
  require('@/assets/image/position_normal.png'),
  require('@/assets/image/position_unnormal.png')
]
export default {
  data() {
    return {
      show: false,
      patTaskId: '',
      taskRoutesLoading: false,
      taskRoutes: []
    }
  },
  methods: {
    closed() {
      this.patTaskId = ''
      this.taskRoutes = []
    },
    open({ patTaskId } = {}) {
      if (!patTaskId) return this.msgError('参数错误，任务ID不能为空')

      this.patTaskId = patTaskId
      this.show = true
      this.getTaskRoutes()
    },
    async getTaskRoutes() {
      const opt = { patTaskId: this.patTaskId }
      this.taskRoutesLoading = true
      const res = await getTaskRoutes(opt).catch(() => false)
      this.taskRoutesLoading = false
      if (res === false) return

      const data = Object.values(res.data || {})
      this.gpsToGCJ02(data)
      this.taskRoutes = data
      this.initMap()
    },
    async gpsToGCJ02(data) {
      // 将 GPS 坐标转为火星坐标
      if (!data.length) return
      data.map(spots => {
        if (!spots?.length) return
        spots.map(spot => {
          if (!spot.longitude || !spot.latitude) return
          const [lng, lat] = wgs84togcj02(spot.longitude, spot.latitude)
          spot.longitude = lng
          spot.latitude = lat
        })
      })
    },
    async gpsToGCJ02_old(data) {
      // 将 GPS 坐标转为火星坐标（app 提交的是未转化的 GPS 坐标）
      // 无数据，或没加载高德
      const aMap = window.AMap
      if (!data.length || !aMap) return

      // 收集含经纬度的点位
      const collectSpots = []
      data.map(spots => {
        if (!spots?.length) return
        spots.map(spot => {
          if (!spot.longitude || !spot.latitude) return
          collectSpots.push(spot)
        })
      })

      // 坐标批量转换
      const lnglats = collectSpots.map(i => [i.longitude, i.latitude])
      const res = await new Promise(resolve => aMap.convertFrom(lnglats, 'gps', (status, result) => resolve(result)))
      // 转换失败
      if (res.info !== 'ok') return

      // 坐标替换
      collectSpots.map((spot, index) => {
        const position = res.locations[index] || {}
        if (!position.lng || !position.lat) return
        spot.longitude = position.lng
        spot.latitude = position.lat
      })
    },
    async initMap() {
      const container = this.$refs.container
      const { taskRoutes } = this
      // 重新赋值，为了解决 eslint 的 no-undef 报错
      const aMap = window.AMap
      if (!aMap) return this.msgError('未加载高德地图组件')

      const ctx = new aMap.Map(container, {
        resizeEnable: true,
        zoom: 16,
        center: initLngLat
      })
      if (!taskRoutes.length) return ctx.setFitView()

      taskRoutes.map(spots => {
        if (!spots?.length) return

        spots.map((spot, index) => {
          if (!spot.longitude || !spot.latitude) return

          // 创建点标记 与 连线
          spot.position = [spot.longitude, spot.latitude]
          const icon = new aMap.Icon({
            image: positionIcons[spot.status],
            size: new aMap.Size(25, 28), // 图标所处区域大小
            imageSize: new aMap.Size(25, 28) // 图标大小
          })
          const marker = new aMap.Marker({ position: spot.position, icon })
          ctx.add(marker)

          // 前一项的位置
          const prePosition = spots[index - 1]?.position || []
          if (index > 0 && prePosition.length) {
            // 两点连线
            const polylinePath = [new aMap.LngLat(prePosition[0], prePosition[1]), new aMap.LngLat(spot.position[0], spot.position[1])]
            const polyline = new aMap.Polyline({ path: polylinePath, strokeColor: '#b9babc' })
            ctx.add(polyline)
          }
        })
      })

      // 自动适配到指定视野范围
      ctx.setFitView()
    }
  }
}
</script>
<style lang="scss" scoped>
.container {
  height: calc(88vh - 100px);
  margin-top: -20px;
}
</style>
